home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / m6805 / m6805.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  36KB  |  1,108 lines

  1. /*** m6805: Portable 6805 emulator ******************************************
  2.  
  3.     m6805.c (Also supports hd68705 and hd63705 variants)
  4.  
  5.     References:
  6.  
  7.         6809 Simulator V09, By L.C. Benschop, Eidnhoven The Netherlands.
  8.  
  9.         m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
  10.             the 6809 Simulator V09)
  11.  
  12.         6809 Microcomputer Programming & Interfacing with Experiments"
  13.             by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.
  14.  
  15.     System dependencies:    UINT16 must be 16 bit unsigned int
  16.                             UINT8 must be 8 bit unsigned int
  17.                             UINT32 must be more than 16 bits
  18.                             arrays up to 65536 bytes must be supported
  19.                             machine must be twos complement
  20.  
  21.   Additional Notes:
  22.  
  23.   K.Wilkins 18/03/99 - Added 63705 functonality and modified all CPU functions
  24.                        necessary to support:
  25.                            Variable width address bus
  26.                            Different stack pointer
  27.                            Alternate boot vectors
  28.                            Alternate interrups vectors
  29.  
  30.  
  31. *****************************************************************************/
  32.  
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include "driver.h"
  37. #include "cpuintrf.h"
  38. #include "state.h"
  39. #include "mamedbg.h"
  40. #include "m6805.h"
  41.  
  42. #define IRQ_LEVEL_DETECT 0
  43.  
  44. static UINT8 m6805_reg_layout[] = {
  45.     M6805_PC, M6805_S, M6805_CC, M6805_A, M6805_X, M6805_IRQ_STATE, 0
  46. };
  47.  
  48. enum {
  49.     SUBTYPE_M6805,
  50.     SUBTYPE_M68705,
  51.     SUBTYPE_HD63705
  52. };
  53.  
  54. /* Layout of the debugger windows x,y,w,h */
  55. static UINT8 m6805_win_layout[] = {
  56.     27, 0,53, 4,    /* register window (top, right rows) */
  57.      0, 0,26,22,    /* disassembler window (left colums) */
  58.     27, 5,53, 8,    /* memory #1 window (right, upper middle) */
  59.     27,14,53, 8,    /* memory #2 window (right, lower middle) */
  60.      0,23,80, 1,    /* command line window (bottom rows) */
  61. };
  62.  
  63. /* 6805 Registers */
  64. typedef struct
  65. {
  66.     int     subtype;        /* Which sub-type is being emulated */
  67.     UINT32    amask;            /* Address bus width */
  68.     UINT32    sp_mask;        /* Stack pointer address mask */
  69.     UINT32    sp_low;         /* Stack pointer low water mark (or floor) */
  70.     PAIR    pc;             /* Program counter */
  71.     PAIR    s;                /* Stack pointer */
  72.     UINT8    a;                /* Accumulator */
  73.     UINT8    x;                /* Index register */
  74.     UINT8    cc;             /* Condition codes */
  75.  
  76.     UINT8    pending_interrupts; /* MB */
  77.     int     (*irq_callback)(int irqline);
  78.     int     irq_state[8];        /* KW Additional lines for HD73705 */
  79.     int        nmi_state;
  80. } m6805_Regs;
  81.  
  82. /* 6805 registers */
  83. static m6805_Regs m6805;
  84.  
  85. #define SUBTYPE    m6805.subtype    /* CPU Type */
  86. #define AMASK    m6805.amask     /* address mask */
  87. #define SP_MASK m6805.sp_mask    /* stack pointer mask */
  88. #define SP_LOW    m6805.sp_low    /* stack pointer low water mark */
  89. #define pPC     m6805.pc        /* program counter PAIR */
  90. #define PC        m6805.pc.w.l    /* program counter lower word */
  91. #define S        m6805.s.w.l     /* stack pointer lower word */
  92. #define A        m6805.a         /* accumulator */
  93. #define X        m6805.x         /* index register */
  94. #define CC        m6805.cc        /* condition codes */
  95.  
  96. static PAIR ea;         /* effective address */
  97. #define EAD ea.d
  98. #define EA  ea.w.l
  99.  
  100. /* public globals */
  101. int m6805_ICount=50000;
  102.  
  103. /* DS -- THESE ARE RE-DEFINED IN m6805.h TO RAM, ROM or FUNCTIONS IN cpuintrf.c */
  104. #define RM(Addr)            M6805_RDMEM((Addr) & AMASK)
  105. #define WM(Addr,Value)        M6805_WRMEM((Addr) & AMASK,Value)
  106. #define M_RDOP(Addr)        M6805_RDOP(Addr)
  107. #define M_RDOP_ARG(Addr)    M6805_RDOP_ARG(Addr)
  108.  
  109. /* macros to tweak the PC and SP */
  110. #define SP_INC    if( ++S > SP_MASK) S = SP_LOW
  111. #define SP_DEC    if( --S < SP_LOW) S = SP_MASK
  112. #define SP_ADJUST(s) ( ( (s) & SP_MASK ) | SP_LOW )
  113.  
  114. /* macros to access memory */
  115. #define IMMBYTE(b) {b = M_RDOP_ARG(PC++);}
  116. #define IMMWORD(w) {w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2;}
  117.  
  118. #define PUSHBYTE(b) wr_s_handler_b(&b)
  119. #define PUSHWORD(w) wr_s_handler_w(&w)
  120. #define PULLBYTE(b) rd_s_handler_b(&b)
  121. #define PULLWORD(w) rd_s_handler_w(&w)
  122.  
  123. /* CC masks      H INZC
  124.               7654 3210    */
  125. #define CFLAG 0x01
  126. #define ZFLAG 0x02
  127. #define NFLAG 0x04
  128. #define IFLAG 0x08
  129. #define HFLAG 0x10
  130.  
  131. #define CLR_NZ      CC&=~(NFLAG|ZFLAG)
  132. #define CLR_HNZC  CC&=~(HFLAG|NFLAG|ZFLAG|CFLAG)
  133. #define CLR_Z      CC&=~(ZFLAG)
  134. #define CLR_NZC   CC&=~(NFLAG|ZFLAG|CFLAG)
  135. #define CLR_ZC      CC&=~(ZFLAG|CFLAG)
  136.  
  137. /* macros for CC -- CC bits affected should be reset before calling */
  138. #define SET_Z(a)       if(!a)SEZ
  139. #define SET_Z8(a)       SET_Z((UINT8)a)
  140. #define SET_N8(a)       CC|=((a&0x80)>>5)
  141. #define SET_H(a,b,r)   CC|=((a^b^r)&0x10)
  142. #define SET_C8(a)       CC|=((a&0x100)>>8)
  143.  
  144. static UINT8 flags8i[256]=     /* increment */
  145. {
  146. 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  147. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  148. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  149. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  150. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  151. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  152. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  153. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  154. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  155. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  156. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  157. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  158. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  159. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  160. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  161. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
  162. };
  163. static UINT8 flags8d[256]= /* decrement */
  164. {
  165. 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  166. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  167. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  168. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  169. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  170. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  171. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  172. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  173. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  174. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  175. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  176. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  177. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  178. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  179. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
  180. 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
  181. };
  182. #define SET_FLAGS8I(a)        {CC|=flags8i[(a)&0xff];}
  183. #define SET_FLAGS8D(a)        {CC|=flags8d[(a)&0xff];}
  184.  
  185. /* combos */
  186. #define SET_NZ8(a)            {SET_N8(a);SET_Z(a);}
  187. #define SET_FLAGS8(a,b,r)    {SET_N8(r);SET_Z8(r);SET_C8(r);}
  188.  
  189. /* for treating an unsigned UINT8 as a signed INT16 */
  190. #define SIGNED(b) ((INT16)(b&0x80?b|0xff00:b))
  191.  
  192. /* Macros for addressing modes */
  193. #define DIRECT EAD=0;IMMBYTE(ea.b.l)
  194. #define IMM8 EA=PC++
  195. #define EXTENDED IMMWORD(ea)
  196. #define INDEXED EA=X
  197. #define INDEXED1 {EAD=0; IMMBYTE(ea.b.l); EA+=X;}
  198. #define INDEXED2 {IMMWORD(ea); EA+=X;}
  199.  
  200. /* macros to set status flags */
  201. #define SEC CC|=CFLAG
  202. #define CLC CC&=~CFLAG
  203. #define SEZ CC|=ZFLAG
  204. #define CLZ CC&=~ZFLAG
  205. #define SEN CC|=NFLAG
  206. #define CLN CC&=~NFLAG
  207. #define SEH CC|=HFLAG
  208. #define CLH CC&=~HFLAG
  209. #define SEI CC|=IFLAG
  210. #define CLI CC&=~IFLAG
  211.  
  212. /* macros for convenience */
  213. #define DIRBYTE(b) {DIRECT;b=RM(EAD);}
  214. #define EXTBYTE(b) {EXTENDED;b=RM(EAD);}
  215. #define IDXBYTE(b) {INDEXED;b=RM(EAD);}
  216. #define IDX1BYTE(b) {INDEXED1;b=RM(EAD);}
  217. #define IDX2BYTE(b) {INDEXED2;b=RM(EAD);}
  218. /* Macros for branch instructions */
  219. #define BRANCH(f) { UINT8 t; IMMBYTE(t); if(f) { PC+=SIGNED(t); } }
  220.  
  221. /* what they say it is ... */
  222. static unsigned char cycles1[] =
  223. {
  224.       /* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
  225.   /*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  226.   /*1*/  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  227.   /*2*/  4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  228.   /*3*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 0, 6, 6, 0,
  229.   /*4*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
  230.   /*5*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
  231.   /*6*/  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7,
  232.   /*7*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6,
  233.   /*8*/  9, 6, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  234.   /*9*/  0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
  235.   /*A*/  2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 8, 2, 0,
  236.   /*B*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5,
  237.   /*C*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
  238.   /*D*/  6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 9, 6, 7,
  239.   /*E*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
  240.   /*F*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
  241. };
  242.  
  243.  
  244. /* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */
  245. #define CLEAR_PAIR(p)   p->d = 0
  246.  
  247. INLINE void rd_s_handler_b( UINT8 *b )
  248. {
  249.     *b = RM( S );
  250.     SP_INC;
  251. }
  252.  
  253. INLINE void rd_s_handler_w( PAIR *p )
  254. {
  255.     CLEAR_PAIR(p);
  256.     p->b.h = RM( S );
  257.     SP_INC;
  258.     p->b.l = RM( S );
  259.     SP_INC;
  260. }
  261.  
  262. INLINE void wr_s_handler_b( UINT8 *b )
  263. {
  264.     SP_DEC;
  265.     WM( S, *b );
  266. }
  267.  
  268. INLINE void wr_s_handler_w( PAIR *p )
  269. {
  270.     SP_DEC;
  271.     WM( S, p->b.l );
  272.     SP_DEC;
  273.     WM( S, p->b.h );
  274. }
  275.  
  276. INLINE void RM16( UINT32 Addr, PAIR *p )
  277. {
  278.     CLEAR_PAIR(p);
  279.     p->b.h = RM(Addr);
  280.     if( ++Addr > AMASK ) Addr = 0;
  281.     p->b.l = RM(Addr);
  282. }
  283.  
  284. INLINE void WM16( UINT32 Addr, PAIR *p )
  285. {
  286.     WM( Addr, p->b.h );
  287.     if( ++Addr > AMASK ) Addr = 0;
  288.     WM( Addr, p->b.l );
  289. }
  290.  
  291. /* Generate interrupts */
  292. static void Interrupt(void)
  293. {
  294.     /* the 6805 latches interrupt requests internally, so we don't clear */
  295.     /* pending_interrupts until the interrupt is taken, no matter what the */
  296.     /* external IRQ pin does. */
  297.  
  298. #if (HAS_HD63705)
  299.     if( (m6805.pending_interrupts & (1<<HD63705_INT_NMI)) != 0)
  300.     {
  301.         PUSHWORD(m6805.pc);
  302.         PUSHBYTE(m6805.x);
  303.         PUSHBYTE(m6805.a);
  304.         PUSHBYTE(m6805.cc);
  305.         SEI;
  306.         /* no vectors supported, just do the callback to clear irq_state if needed */
  307.         if (m6805.irq_callback)
  308.             (*m6805.irq_callback)(0);
  309.  
  310.         RM16( 0x1ffc, &pPC);
  311.         m6805.pending_interrupts &= ~(1<<HD63705_INT_NMI);
  312.  
  313.         m6805_ICount -= 11;
  314.  
  315.     }
  316.     else if( (m6805.pending_interrupts & (M6805_INT_IRQ|HD63705_INT_MASK)) != 0 && (CC & IFLAG) == 0 )
  317. #else
  318.     if( (m6805.pending_interrupts & M6805_INT_IRQ) != 0 && (CC & IFLAG) == 0 )
  319. #endif
  320.     {
  321.         /* standard IRQ */
  322. #if (HAS_HD63705)
  323.         if(SUBTYPE!=SUBTYPE_HD63705)
  324. #endif
  325.             PC |= 0xf800;
  326.         PUSHWORD(m6805.pc);
  327.         PUSHBYTE(m6805.x);
  328.         PUSHBYTE(m6805.a);
  329.         PUSHBYTE(m6805.cc);
  330.         SEI;
  331.         /* no vectors supported, just do the callback to clear irq_state if needed */
  332.         if (m6805.irq_callback)
  333.             (*m6805.irq_callback)(0);
  334.  
  335.  
  336. #if (HAS_HD63705)
  337.         if(SUBTYPE==SUBTYPE_HD63705)
  338.         {
  339.             /* Need to add emulation of other interrupt sources here KW-2/4/99 */
  340.             /* This is just a quick patch for Namco System 2 operation         */
  341.  
  342.             if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ1))!=0)
  343.             {
  344.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ1);
  345.                 RM16( 0x1ff8, &pPC);
  346.             }
  347.             else if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ2))!=0)
  348.             {
  349.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ2);
  350.                 RM16( 0x1fec, &pPC);
  351.             }
  352.             else if((m6805.pending_interrupts&(1<<HD63705_INT_ADCONV))!=0)
  353.             {
  354.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_ADCONV);
  355.                 RM16( 0x1fea, &pPC);
  356.             }
  357.             else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER1))!=0)
  358.             {
  359.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER1);
  360.                 RM16( 0x1ff6, &pPC);
  361.             }
  362.             else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER2))!=0)
  363.             {
  364.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER2);
  365.                 RM16( 0x1ff4, &pPC);
  366.             }
  367.             else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER3))!=0)
  368.             {
  369.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
  370.                 RM16( 0x1ff2, &pPC);
  371.             }
  372.             else if((m6805.pending_interrupts&(1<<HD63705_INT_PCI))!=0)
  373.             {
  374.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_PCI);
  375.                 RM16( 0x1ff0, &pPC);
  376.             }
  377.             else if((m6805.pending_interrupts&(1<<HD63705_INT_SCI))!=0)
  378.             {
  379.                 m6805.pending_interrupts &= ~(1<<HD63705_INT_SCI);
  380.                 RM16( 0x1fee, &pPC);
  381.             }
  382.         }
  383.         else
  384. #endif
  385.         {
  386.             m6805.pending_interrupts &= ~M6805_INT_IRQ;
  387.             RM16( AMASK - 5, &pPC );
  388.         }
  389.         m6805_ICount -= 11;
  390.     }
  391. }
  392.  
  393.  
  394. void m6805_reset(void *param)
  395. {
  396.     memset(&m6805, 0, sizeof(m6805));
  397.     /* Force CPU sub-type and relevant masks */
  398.     m6805.subtype    = SUBTYPE_M6805;
  399.     AMASK    = 0x7ff;
  400.     SP_MASK = 0x07f;
  401.     SP_LOW    = 0x060;
  402.     /* Initial stack pointer */
  403.     S = SP_MASK;
  404.     /* IRQ disabled */
  405.     SEI;
  406.     RM16( AMASK - 1 , &pPC );
  407. }
  408.  
  409. void m6805_exit(void)
  410. {
  411.     /* nothing to do */
  412. }
  413.  
  414. /****************************************************************************
  415.  * Get all registers in given buffer
  416.  ****************************************************************************/
  417. unsigned m6805_get_context(void *dst)
  418. {
  419.     if( dst )
  420.         *(m6805_Regs*)dst = m6805;
  421.     return sizeof(m6805_Regs);
  422. }
  423.  
  424.  
  425. /****************************************************************************
  426.  * Set all registers to given values
  427.  ****************************************************************************/
  428. void m6805_set_context(void *src)
  429. {
  430.     if( src )
  431.     {
  432.         m6805 = *(m6805_Regs*)src;
  433.         S = SP_ADJUST( S );
  434.     }
  435. }
  436.  
  437.  
  438. /****************************************************************************
  439.  * Return program counter
  440.  ****************************************************************************/
  441. unsigned m6805_get_pc(void)
  442. {
  443.     return PC & AMASK;
  444. }
  445.  
  446.  
  447. /****************************************************************************
  448.  * Set program counter
  449.  ****************************************************************************/
  450. void m6805_set_pc(unsigned val)
  451. {
  452.     PC = val & AMASK;
  453. }
  454.  
  455.  
  456. /****************************************************************************
  457.  * Return stack pointer
  458.  ****************************************************************************/
  459. unsigned m6805_get_sp(void)
  460. {
  461.     return SP_ADJUST(S);
  462. }
  463.  
  464.  
  465. /****************************************************************************
  466.  * Set stack pointer
  467.  ****************************************************************************/
  468. void m6805_set_sp(unsigned val)
  469. {
  470.     S = SP_ADJUST(val);
  471. }
  472.  
  473.  
  474. /****************************************************************************
  475.  * Return a specific register
  476.  ****************************************************************************/
  477. unsigned m6805_get_reg(int regnum)
  478. {
  479.     switch( regnum )
  480.     {
  481.         case M6805_A: return A;
  482.         case M6805_PC: return PC;
  483.         case M6805_S: return SP_ADJUST(S);
  484.         case M6805_X: return X;
  485.         case M6805_CC: return CC;
  486.         case M6805_IRQ_STATE: return m6805.irq_state[0];
  487.         default:
  488.             if( regnum < REG_SP_CONTENTS )
  489.             {
  490.                 unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
  491.                 if( offset < SP_MASK )
  492.                     return (RM( offset ) << 8) | RM( offset+1 );
  493.             }
  494.     }
  495.     return 0;
  496. }
  497.  
  498.  
  499. /****************************************************************************
  500.  * Set a specific register
  501.  ****************************************************************************/
  502. void m6805_set_reg(int regnum, unsigned val)
  503. {
  504.     switch( regnum )
  505.     {
  506.         case M6805_A: A = val; break;
  507.         case M6805_PC: PC = val & AMASK; break;
  508.         case M6805_S: S = SP_ADJUST(val); break;
  509.         case M6805_X: X = val; break;
  510.         case M6805_CC: CC = val; break;
  511.         case M6805_IRQ_STATE: m6805_set_irq_line(0,val); break;
  512.         default:
  513.             if( regnum < REG_SP_CONTENTS )
  514.             {
  515.                 unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
  516.                 if( offset < SP_MASK )
  517.                 {
  518.                     WM( offset, (val >> 8) & 0xff );
  519.                     WM( offset+1, val & 0xff );
  520.                 }
  521.             }
  522.     }
  523. }
  524.  
  525.  
  526. void m6805_set_nmi_line(int state)
  527. {
  528.     /* 6805 has no NMI line... but the HD63705 does !! see specific version */
  529. }
  530.  
  531. void m6805_set_irq_line(int irqline, int state)
  532. {
  533.     /* Basic 6805 only has one IRQ line */
  534.     /* See HD63705 specific version     */
  535.     if (m6805.irq_state[0] == state) return;
  536.  
  537.     m6805.irq_state[0] = state;
  538.     if (state != CLEAR_LINE)
  539.         m6805.pending_interrupts |= M6805_INT_IRQ;
  540. }
  541.  
  542. void m6805_set_irq_callback(int (*callback)(int irqline))
  543. {
  544.     m6805.irq_callback = callback;
  545. }
  546.  
  547. static void state_save(void *file, const char *module)
  548. {
  549.     int cpu = cpu_getactivecpu();
  550.     state_save_UINT8(file,module,cpu,"A", &A, 1);
  551.     state_save_UINT16(file,module,cpu,"PC", &PC, 1);
  552.     state_save_UINT16(file,module,cpu,"S", &S, 1);
  553.     state_save_UINT8(file,module,cpu,"X", &X, 1);
  554.     state_save_UINT8(file,module,cpu,"CC", &CC, 1);
  555.     state_save_UINT8(file,module,cpu,"PENDING", &m6805.pending_interrupts, 1);
  556.     state_save_INT32(file,module,cpu,"IRQ_STATE", &m6805.irq_state[0], 1);
  557. }
  558.  
  559. static void state_load(void *file, const char *module)
  560. {
  561.     int cpu = cpu_getactivecpu();
  562.     state_load_UINT8(file,module,cpu,"A", &A, 1);
  563.     state_load_UINT16(file,module,cpu,"PC", &PC, 1);
  564.     state_load_UINT16(file,module,cpu,"S", &S, 1);
  565.     state_load_UINT8(file,module,cpu,"X", &X, 1);
  566.     state_load_UINT8(file,module,cpu,"CC", &CC, 1);
  567.     state_load_UINT8(file,module,cpu,"PENDING", &m6805.pending_interrupts, 1);
  568.     state_load_INT32(file,module,cpu,"IRQ_STATE", &m6805.irq_state[0], 1);
  569. }
  570.  
  571. void m6805_state_save(void *file) { state_save(file,"m6805"); }
  572. void m6805_state_load(void *file) { state_load(file,"m6805"); }
  573.  
  574. #include "6805ops.c"
  575.  
  576.  
  577. /* execute instructions on this CPU until icount expires */
  578. int m6805_execute(int cycles)
  579. {
  580.     UINT8 ireg;
  581.     m6805_ICount = cycles;
  582.  
  583.     do
  584.     {
  585.         if (m6805.pending_interrupts != 0)
  586.             Interrupt();
  587.  
  588.         CALL_MAME_DEBUG;
  589.  
  590.         ireg=M_RDOP(PC++);
  591.  
  592.         switch( ireg )
  593.         {
  594.             case 0x00: brset(0x01); break;
  595.             case 0x01: brclr(0x01); break;
  596.             case 0x02: brset(0x02); break;
  597.             case 0x03: brclr(0x02); break;
  598.             case 0x04: brset(0x04); break;
  599.             case 0x05: brclr(0x04); break;
  600.             case 0x06: brset(0x08); break;
  601.             case 0x07: brclr(0x08); break;
  602.             case 0x08: brset(0x10); break;
  603.             case 0x09: brclr(0x10); break;
  604.             case 0x0A: brset(0x20); break;
  605.             case 0x0B: brclr(0x20); break;
  606.             case 0x0C: brset(0x40); break;
  607.             case 0x0D: brclr(0x40); break;
  608.             case 0x0E: brset(0x80); break;
  609.             case 0x0F: brclr(0x80); break;
  610.             case 0x10: bset(0x01); break;
  611.             case 0x11: bclr(0x01); break;
  612.             case 0x12: bset(0x02); break;
  613.             case 0x13: bclr(0x02); break;
  614.             case 0x14: bset(0x04); break;
  615.             case 0x15: bclr(0x04); break;
  616.             case 0x16: bset(0x08); break;
  617.             case 0x17: bclr(0x08); break;
  618.             case 0x18: bset(0x10); break;
  619.             case 0x19: bclr(0x10); break;
  620.             case 0x1a: bset(0x20); break;
  621.             case 0x1b: bclr(0x20); break;
  622.             case 0x1c: bset(0x40); break;
  623.             case 0x1d: bclr(0x40); break;
  624.             case 0x1e: bset(0x80); break;
  625.             case 0x1f: bclr(0x80); break;
  626.             case 0x20: bra(); break;
  627.             case 0x21: brn(); break;
  628.             case 0x22: bhi(); break;
  629.             case 0x23: bls(); break;
  630.             case 0x24: bcc(); break;
  631.             case 0x25: bcs(); break;
  632.             case 0x26: bne(); break;
  633.             case 0x27: beq(); break;
  634.             case 0x28: bhcc(); break;
  635.             case 0x29: bhcs(); break;
  636.             case 0x2a: bpl(); break;
  637.             case 0x2b: bmi(); break;
  638.             case 0x2c: bmc(); break;
  639.             case 0x2d: bms(); break;
  640.             case 0x2e: bil(); break;
  641.             case 0x2f: bih(); break;
  642.             case 0x30: neg_di(); break;
  643.             case 0x31: illegal(); break;
  644.             case 0x32: illegal(); break;
  645.             case 0x33: com_di(); break;
  646.             case 0x34: lsr_di(); break;
  647.             case 0x35: illegal(); break;
  648.             case 0x36: ror_di(); break;
  649.             case 0x37: asr_di(); break;
  650.             case 0x38: lsl_di(); break;
  651.             case 0x39: rol_di(); break;
  652.             case 0x3a: dec_di(); break;
  653.             case 0x3b: illegal(); break;
  654.             case 0x3c: inc_di(); break;
  655.             case 0x3d: tst_di(); break;
  656.             case 0x3e: illegal(); break;
  657.             case 0x3f: clr_di(); break;
  658.             case 0x40: nega(); break;
  659.             case 0x41: illegal(); break;
  660.             case 0x42: illegal(); break;
  661.             case 0x43: coma(); break;
  662.             case 0x44: lsra(); break;
  663.             case 0x45: illegal(); break;
  664.             case 0x46: rora(); break;
  665.             case 0x47: asra(); break;
  666.             case 0x48: lsla(); break;
  667.             case 0x49: rola(); break;
  668.             case 0x4a: deca(); break;
  669.             case 0x4b: illegal(); break;
  670.             case 0x4c: inca(); break;
  671.             case 0x4d: tsta(); break;
  672.             case 0x4e: illegal(); break;
  673.             case 0x4f: clra(); break;
  674.             case 0x50: negx(); break;
  675.             case 0x51: illegal(); break;
  676.             case 0x52: illegal(); break;
  677.             case 0x53: comx(); break;
  678.             case 0x54: lsrx(); break;
  679.             case 0x55: illegal(); break;
  680.             case 0x56: rorx(); break;
  681.             case 0x57: asrx(); break;
  682.             case 0x58: aslx(); break;
  683.             case 0x59: rolx(); break;
  684.             case 0x5a: decx(); break;
  685.             case 0x5b: illegal(); break;
  686.             case 0x5c: incx(); break;
  687.             case 0x5d: tstx(); break;
  688.             case 0x5e: illegal(); break;
  689.             case 0x5f: clrx(); break;
  690.             case 0x60: neg_ix1(); break;
  691.             case 0x61: illegal(); break;
  692.             case 0x62: illegal(); break;
  693.             case 0x63: com_ix1(); break;
  694.             case 0x64: lsr_ix1(); break;
  695.             case 0x65: illegal(); break;
  696.             case 0x66: ror_ix1(); break;
  697.             case 0x67: asr_ix1(); break;
  698.             case 0x68: lsl_ix1(); break;
  699.             case 0x69: rol_ix1(); break;
  700.             case 0x6a: dec_ix1(); break;
  701.             case 0x6b: illegal(); break;
  702.             case 0x6c: inc_ix1(); break;
  703.             case 0x6d: tst_ix1(); break;
  704.             case 0x6e: illegal(); break;
  705.             case 0x6f: clr_ix1(); break;
  706.             case 0x70: neg_ix(); break;
  707.             case 0x71: illegal(); break;
  708.             case 0x72: illegal(); break;
  709.             case 0x73: com_ix(); break;
  710.             case 0x74: lsr_ix(); break;
  711.             case 0x75: illegal(); break;
  712.             case 0x76: ror_ix(); break;
  713.             case 0x77: asr_ix(); break;
  714.             case 0x78: lsl_ix(); break;
  715.             case 0x79: rol_ix(); break;
  716.             case 0x7a: dec_ix(); break;
  717.             case 0x7b: illegal(); break;
  718.             case 0x7c: inc_ix(); break;
  719.             case 0x7d: tst_ix(); break;
  720.             case 0x7e: illegal(); break;
  721.             case 0x7f: clr_ix(); break;
  722.             case 0x80: rti(); break;
  723.             case 0x81: rts(); break;
  724.             case 0x82: illegal(); break;
  725.             case 0x83: swi(); break;
  726.             case 0x84: illegal(); break;
  727.             case 0x85: illegal(); break;
  728.             case 0x86: illegal(); break;
  729.             case 0x87: illegal(); break;
  730.             case 0x88: illegal(); break;
  731.             case 0x89: illegal(); break;
  732.             case 0x8a: illegal(); break;
  733.             case 0x8b: illegal(); break;
  734.             case 0x8c: illegal(); break;
  735.             case 0x8d: illegal(); break;
  736.             case 0x8e: illegal(); break;
  737.             case 0x8f: illegal(); break;
  738.             case 0x90: illegal(); break;
  739.             case 0x91: illegal(); break;
  740.             case 0x92: illegal(); break;
  741.             case 0x93: illegal(); break;
  742.             case 0x94: illegal(); break;
  743.             case 0x95: illegal(); break;
  744.             case 0x96: illegal(); break;
  745.             case 0x97: tax(); break;
  746.             case 0x98: CLC; break;
  747.             case 0x99: SEC; break;
  748. #if IRQ_LEVEL_DETECT
  749.             case 0x9a: CLI; if (m6805.irq_state != CLEAR_LINE) m6805.pending_interrupts |= M6805_INT_IRQ; break;
  750. #else
  751.             case 0x9a: CLI; break;
  752. #endif
  753.             case 0x9b: SEI; break;
  754.             case 0x9c: rsp(); break;
  755.             case 0x9d: nop(); break;
  756.             case 0x9e: illegal(); break;
  757.             case 0x9f: txa(); break;
  758.             case 0xa0: suba_im(); break;
  759.             case 0xa1: cmpa_im(); break;
  760.             case 0xa2: sbca_im(); break;
  761.             case 0xa3: cpx_im(); break;
  762.             case 0xa4: anda_im(); break;
  763.             case 0xa5: bita_im(); break;
  764.             case 0xa6: lda_im(); break;
  765.             case 0xa7: illegal(); break;
  766.             case 0xa8: eora_im(); break;
  767.             case 0xa9: adca_im(); break;
  768.             case 0xaa: ora_im(); break;
  769.             case 0xab: adda_im(); break;
  770.             case 0xac: illegal(); break;
  771.             case 0xad: bsr(); break;
  772.             case 0xae: ldx_im(); break;
  773.             case 0xaf: illegal(); break;
  774.             case 0xb0: suba_di(); break;
  775.             case 0xb1: cmpa_di(); break;
  776.             case 0xb2: sbca_di(); break;
  777.             case 0xb3: cpx_di(); break;
  778.             case 0xb4: anda_di(); break;
  779.             case 0xb5: bita_di(); break;
  780.             case 0xb6: lda_di(); break;
  781.             case 0xb7: sta_di(); break;
  782.             case 0xb8: eora_di(); break;
  783.             case 0xb9: adca_di(); break;
  784.             case 0xba: ora_di(); break;
  785.             case 0xbb: adda_di(); break;
  786.             case 0xbc: jmp_di(); break;
  787.             case 0xbd: jsr_di(); break;
  788.             case 0xbe: ldx_di(); break;
  789.             case 0xbf: stx_di(); break;
  790.             case 0xc0: suba_ex(); break;
  791.             case 0xc1: cmpa_ex(); break;
  792.             case 0xc2: sbca_ex(); break;
  793.             case 0xc3: cpx_ex(); break;
  794.             case 0xc4: anda_ex(); break;
  795.             case 0xc5: bita_ex(); break;
  796.             case 0xc6: lda_ex(); break;
  797.             case 0xc7: sta_ex(); break;
  798.             case 0xc8: eora_ex(); break;
  799.             case 0xc9: adca_ex(); break;
  800.             case 0xca: ora_ex(); break;
  801.             case 0xcb: adda_ex(); break;
  802.             case 0xcc: jmp_ex(); break;
  803.             case 0xcd: jsr_ex(); break;
  804.             case 0xce: ldx_ex(); break;
  805.             case 0xcf: stx_ex(); break;
  806.             case 0xd0: suba_ix2(); break;
  807.             case 0xd1: cmpa_ix2(); break;
  808.             case 0xd2: sbca_ix2(); break;
  809.             case 0xd3: cpx_ix2(); break;
  810.             case 0xd4: anda_ix2(); break;
  811.             case 0xd5: bita_ix2(); break;
  812.             case 0xd6: lda_ix2(); break;
  813.             case 0xd7: sta_ix2(); break;
  814.             case 0xd8: eora_ix2(); break;
  815.             case 0xd9: adca_ix2(); break;
  816.             case 0xda: ora_ix2(); break;
  817.             case 0xdb: adda_ix2(); break;
  818.             case 0xdc: jmp_ix2(); break;
  819.             case 0xdd: jsr_ix2(); break;
  820.             case 0xde: ldx_ix2(); break;
  821.             case 0xdf: stx_ix2(); break;
  822.             case 0xe0: suba_ix1(); break;
  823.             case 0xe1: cmpa_ix1(); break;
  824.             case 0xe2: sbca_ix1(); break;
  825.             case 0xe3: cpx_ix1(); break;
  826.             case 0xe4: anda_ix1(); break;
  827.             case 0xe5: bita_ix1(); break;
  828.             case 0xe6: lda_ix1(); break;
  829.             case 0xe7: sta_ix1(); break;
  830.             case 0xe8: eora_ix1(); break;
  831.             case 0xe9: adca_ix1(); break;
  832.             case 0xea: ora_ix1(); break;
  833.             case 0xeb: adda_ix1(); break;
  834.             case 0xec: jmp_ix1(); break;
  835.             case 0xed: jsr_ix1(); break;
  836.             case 0xee: ldx_ix1(); break;
  837.             case 0xef: stx_ix1(); break;
  838.             case 0xf0: suba_ix(); break;
  839.             case 0xf1: cmpa_ix(); break;
  840.             case 0xf2: sbca_ix(); break;
  841.             case 0xf3: cpx_ix(); break;
  842.             case 0xf4: anda_ix(); break;
  843.             case 0xf5: bita_ix(); break;
  844.             case 0xf6: lda_ix(); break;
  845.             case 0xf7: sta_ix(); break;
  846.             case 0xf8: eora_ix(); break;
  847.             case 0xf9: adca_ix(); break;
  848.             case 0xfa: ora_ix(); break;
  849.             case 0xfb: adda_ix(); break;
  850.             case 0xfc: jmp_ix(); break;
  851.             case 0xfd: jsr_ix(); break;
  852.             case 0xfe: ldx_ix(); break;
  853.             case 0xff: stx_ix(); break;
  854.         }
  855.         m6805_ICount -= cycles1[ireg];
  856.     } while( m6805_ICount > 0 );
  857.  
  858.     return cycles - m6805_ICount;
  859. }
  860.  
  861. /****************************************************************************
  862.  * Return a formatted string for a register
  863.  ****************************************************************************/
  864. const char *m6805_info(void *context, int regnum)
  865. {
  866.     static char buffer[8][47+1];
  867.     static int which = 0;
  868.     m6805_Regs *r = context;
  869.  
  870.     which = ++which % 8;
  871.     buffer[which][0] = '\0';
  872.  
  873.     if( !context )
  874.         r = &m6805;
  875.  
  876.     switch( regnum )
  877.     {
  878.         case CPU_INFO_NAME: return "M6805";
  879.         case CPU_INFO_FAMILY: return "Motorola 6805";
  880.         case CPU_INFO_VERSION: return "1.0";
  881.         case CPU_INFO_FILE: return __FILE__;
  882.         case CPU_INFO_CREDITS: return "The MAME team.";
  883.         case CPU_INFO_REG_LAYOUT: return (const char *)m6805_reg_layout;
  884.         case CPU_INFO_WIN_LAYOUT: return (const char *)m6805_win_layout;
  885.  
  886.         case CPU_INFO_FLAGS:
  887.             sprintf(buffer[which], "%c%c%c%c%c%c%c%c",
  888.                 r->cc & 0x80 ? '?':'.',
  889.                 r->cc & 0x40 ? '?':'.',
  890.                 r->cc & 0x20 ? '?':'.',
  891.                 r->cc & 0x10 ? 'H':'.',
  892.                 r->cc & 0x08 ? 'I':'.',
  893.                 r->cc & 0x04 ? 'N':'.',
  894.                 r->cc & 0x02 ? 'Z':'.',
  895.                 r->cc & 0x01 ? 'C':'.');
  896.             break;
  897.         case CPU_INFO_REG+M6805_A: sprintf(buffer[which], "A:%02X", r->a); break;
  898.         case CPU_INFO_REG+M6805_PC: sprintf(buffer[which], "PC:%04X", r->pc.w.l); break;
  899.         case CPU_INFO_REG+M6805_S: sprintf(buffer[which], "S:%02X", r->s.w.l); break;
  900.         case CPU_INFO_REG+M6805_X: sprintf(buffer[which], "X:%02X", r->x); break;
  901.         case CPU_INFO_REG+M6805_CC: sprintf(buffer[which], "CC:%02X", r->cc); break;
  902.         case CPU_INFO_REG+M6805_IRQ_STATE: sprintf(buffer[which], "IRQ:%X", r->irq_state[0]); break;
  903.     }
  904.     return buffer[which];
  905. }
  906.  
  907. unsigned m6805_dasm(char *buffer, unsigned pc)
  908. {
  909. #ifdef MAME_DEBUG
  910.     return Dasm6805(buffer,pc);
  911. #else
  912.     sprintf( buffer, "$%02X", cpu_readop(pc) );
  913.     return 1;
  914. #endif
  915. }
  916.  
  917. /****************************************************************************
  918.  * M68705 section
  919.  ****************************************************************************/
  920. #if (HAS_M68705)
  921. static UINT8 m68705_reg_layout[] = {
  922.     M68705_PC, M68705_S, M68705_CC, M68705_A, M68705_X, M68705_IRQ_STATE, 0
  923. };
  924.  
  925. /* Layout of the debugger windows x,y,w,h */
  926. static UINT8 m68705_win_layout[] = {
  927.     27, 0,53, 4,    /* register window (top, right rows) */
  928.      0, 0,26,22,    /* disassembler window (left colums) */
  929.     27, 5,53, 8,    /* memory #1 window (right, upper middle) */
  930.     27,14,53, 8,    /* memory #2 window (right, lower middle) */
  931.      0,23,80, 1,    /* command line window (bottom rows) */
  932. };
  933.  
  934. void m68705_reset(void *param)
  935. {
  936.     m6805_reset(param);
  937.     /* Overide default 6805 type */
  938.     m6805.subtype = SUBTYPE_M68705;
  939. }
  940. void m68705_exit(void) { m6805_exit(); }
  941. int  m68705_execute(int cycles) { return m6805_execute(cycles); }
  942. unsigned m68705_get_context(void *dst) { return m6805_get_context(dst); }
  943. void m68705_set_context(void *src) { m6805_set_context(src); }
  944. unsigned m68705_get_pc(void) { return m6805_get_pc(); }
  945. void m68705_set_pc(unsigned val) { m6805_set_pc(val); }
  946. unsigned m68705_get_sp(void) { return m6805_get_sp(); }
  947. void m68705_set_sp(unsigned val) { m6805_set_pc(val); }
  948. unsigned m68705_get_reg(int regnum)  { return m6805_get_reg(regnum); }
  949. void m68705_set_reg(int regnum, unsigned val)  { m6805_set_reg(regnum,val); }
  950. void m68705_set_nmi_line(int state)  { m6805_set_nmi_line(state); }
  951. void m68705_set_irq_line(int irqline, int state)  { m6805_set_irq_line(irqline,state); }
  952. void m68705_set_irq_callback(int (*callback)(int irqline))    { m6805_set_irq_callback(callback); }
  953. void m68705_state_save(void *file) { state_save(file,"m68705"); }
  954. void m68705_state_load(void *file) { state_load(file,"m68705"); }
  955.  
  956. const char *m68705_info(void *context, int regnum)
  957. {
  958.     switch( regnum )
  959.     {
  960.         case CPU_INFO_NAME: return "M68705";
  961.         case CPU_INFO_VERSION: return "1.1";
  962.         case CPU_INFO_REG_LAYOUT: return (const char*)m68705_reg_layout;
  963.         case CPU_INFO_WIN_LAYOUT: return (const char*)m68705_win_layout;
  964.     }
  965.     return m6805_info(context,regnum);
  966. }
  967.  
  968. unsigned m68705_dasm(char *buffer, unsigned pc)
  969. {
  970. #ifdef MAME_DEBUG
  971.     return Dasm6805(buffer,pc);
  972. #else
  973.     sprintf( buffer, "$%02X", cpu_readop(pc) );
  974.     return 1;
  975. #endif
  976. }
  977. #endif
  978.  
  979. /****************************************************************************
  980.  * HD63705 section
  981.  ****************************************************************************/
  982. #if (HAS_HD63705)
  983. static UINT8 hd63705_reg_layout[] = {
  984.     HD63705_PC, HD63705_S, HD63705_CC, HD63705_A, HD63705_X, -1,-1,
  985.     HD63705_NMI_STATE, HD63705_IRQ1_STATE, HD63705_IRQ2_STATE, HD63705_ADCONV_STATE,0
  986. };
  987.  
  988. /* Layout of the debugger windows x,y,w,h */
  989. static UINT8 hd63705_win_layout[] = {
  990.     27, 0,53, 4,    /* register window (top, right rows) */
  991.      0, 0,26,22,    /* disassembler window (left colums) */
  992.     27, 5,53, 8,    /* memory #1 window (right, upper middle) */
  993.     27,14,53, 8,    /* memory #2 window (right, lower middle) */
  994.      0,23,80, 1,    /* command line window (bottom rows) */
  995. };
  996.  
  997. void hd63705_reset(void *param)
  998. {
  999.     m6805_reset(param);
  1000.  
  1001.     /* Overide default 6805 types */
  1002.     m6805.subtype    = SUBTYPE_HD63705;
  1003.     AMASK    = 0xffff;
  1004.     SP_MASK = 0x17f;
  1005.     SP_LOW    = 0x100;
  1006.     RM16( 0x1ffe, &m6805.pc );
  1007.     S = 0x17f;
  1008. }
  1009. void hd63705_exit(void) { m6805_exit(); }
  1010. int    hd63705_execute(int cycles) { return m6805_execute(cycles); }
  1011. unsigned hd63705_get_context(void *dst) { return m6805_get_context(dst); }
  1012. void hd63705_set_context(void *src) { m6805_set_context(src); }
  1013. unsigned hd63705_get_pc(void) { return m6805_get_pc(); }
  1014. void hd63705_set_pc(unsigned val) { m6805_set_pc(val); }
  1015. unsigned hd63705_get_sp(void) { return m6805_get_sp(); }
  1016. void hd63705_set_sp(unsigned val) { m6805_set_pc(val); }
  1017.  
  1018. unsigned hd63705_get_reg(int regnum)  { return m6805_get_reg(regnum); }
  1019. void hd63705_set_reg(int regnum, unsigned val)  { m6805_set_reg(regnum,val); }
  1020.  
  1021. void hd63705_set_nmi_line(int state)
  1022. {
  1023.     if (m6805.nmi_state == state) return;
  1024.  
  1025.     m6805.nmi_state = state;
  1026.     if (state != CLEAR_LINE)
  1027.         m6805.pending_interrupts |= HD63705_INT_NMI;
  1028. }
  1029.  
  1030. void hd63705_set_irq_line(int irqline, int state)
  1031. {
  1032.     if(irqline>HD63705_INT_ADCONV) return;
  1033.  
  1034.     if (m6805.irq_state[irqline] == state) return;
  1035.     m6805.irq_state[irqline] = state;
  1036.     if (state != CLEAR_LINE) m6805.pending_interrupts |= 1<<irqline;
  1037. }
  1038.  
  1039. void hd63705_set_irq_callback(int (*callback)(int irqline))  { m6805_set_irq_callback(callback); }
  1040.  
  1041. void hd63705_state_save(void *file)
  1042. {
  1043.     int cpu = cpu_getactivecpu();
  1044.     char module[8]="hd63705";
  1045.     state_save(file,module);
  1046.     state_save_INT32(file,module,cpu,"IRQ1_STATE", &m6805.irq_state[0], 1);
  1047.     state_save_INT32(file,module,cpu,"IRQ2_STATE", &m6805.irq_state[1], 1);
  1048.     state_save_INT32(file,module,cpu,"TIMER1_STATE", &m6805.irq_state[2], 1);
  1049.     state_save_INT32(file,module,cpu,"TIMER2_STATE", &m6805.irq_state[3], 1);
  1050.     state_save_INT32(file,module,cpu,"TIMER3_STATE", &m6805.irq_state[4], 1);
  1051.     state_save_INT32(file,module,cpu,"PCI_STATE", &m6805.irq_state[5], 1);
  1052.     state_save_INT32(file,module,cpu,"SCI_STATE", &m6805.irq_state[6], 1);
  1053.     state_save_INT32(file,module,cpu,"ADCONV_STATE", &m6805.irq_state[7], 1);
  1054. }
  1055.  
  1056. void hd63705_state_load(void *file)
  1057. {
  1058.     int cpu = cpu_getactivecpu();
  1059.     char module[8]="hd63705";
  1060.     state_load(file,module);
  1061.     state_load_INT32(file,module,cpu,"IRQ1_STATE", &m6805.irq_state[0], 1);
  1062.     state_load_INT32(file,module,cpu,"IRQ2_STATE", &m6805.irq_state[1], 1);
  1063.     state_load_INT32(file,module,cpu,"TIMER1_STATE", &m6805.irq_state[2], 1);
  1064.     state_load_INT32(file,module,cpu,"TIMER2_STATE", &m6805.irq_state[3], 1);
  1065.     state_load_INT32(file,module,cpu,"TIMER3_STATE", &m6805.irq_state[4], 1);
  1066.     state_load_INT32(file,module,cpu,"PCI_STATE", &m6805.irq_state[5], 1);
  1067.     state_load_INT32(file,module,cpu,"SCI_STATE", &m6805.irq_state[6], 1);
  1068.     state_load_INT32(file,module,cpu,"ADCONV_STATE", &m6805.irq_state[7], 1);
  1069. }
  1070.  
  1071. const char *hd63705_info(void *context, int regnum)
  1072. {
  1073.     static char buffer[8][47+1];
  1074.     static int which = 0;
  1075.     m6805_Regs *r = context;
  1076.  
  1077.     which = ++which % 8;
  1078.     buffer[which][0] = '\0';
  1079.  
  1080.     if( !context )
  1081.         r = &m6805;
  1082.  
  1083.     switch( regnum )
  1084.     {
  1085.         case CPU_INFO_NAME: return "HD63705";
  1086.         case CPU_INFO_VERSION: return "1.0";
  1087.         case CPU_INFO_CREDITS: return "Keith Wilkins, Juergen Buchmueller";
  1088.         case CPU_INFO_REG_LAYOUT: return (const char *)hd63705_reg_layout;
  1089.         case CPU_INFO_WIN_LAYOUT: return (const char *)hd63705_win_layout;
  1090.         case CPU_INFO_REG+HD63705_NMI_STATE: sprintf(buffer[which], "NMI:%X", r->nmi_state); return buffer[which];
  1091.         case CPU_INFO_REG+HD63705_IRQ1_STATE: sprintf(buffer[which], "IRQ1:%X", r->irq_state[HD63705_INT_IRQ1]); return buffer[which];
  1092.         case CPU_INFO_REG+HD63705_IRQ2_STATE: sprintf(buffer[which], "IRQ2:%X", r->irq_state[HD63705_INT_IRQ2]); return buffer[which];
  1093.         case CPU_INFO_REG+HD63705_ADCONV_STATE: sprintf(buffer[which], "ADCONV:%X", r->irq_state[HD63705_INT_ADCONV]); return buffer[which];
  1094.     }
  1095.     return m6805_info(context,regnum);
  1096. }
  1097.  
  1098. unsigned hd63705_dasm(char *buffer, unsigned pc)
  1099. {
  1100. #ifdef MAME_DEBUG
  1101.     return Dasm6805(buffer,pc);
  1102. #else
  1103.     sprintf( buffer, "$%02X", cpu_readop(pc) );
  1104.     return 1;
  1105. #endif
  1106. }
  1107. #endif
  1108.